package com.huluspace.learnhub.service;

import com.huluspace.learnhub.dto.*;
import com.huluspace.learnhub.model.Role;
import com.huluspace.learnhub.model.User;
import com.huluspace.learnhub.repository.RoleRepository;
import com.huluspace.learnhub.repository.UserRepository;
import com.huluspace.learnhub.security.JwtUtil;
import jakarta.persistence.criteria.Predicate;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class UserService {
  private final UserRepository userRepository;
  private final RoleRepository roleRepository;
  private final PasswordEncoder passwordEncoder;
  private final JwtUtil jwtUtil;
  public UserService(UserRepository userRepository,
                     RoleRepository roleRepository,
                     PasswordEncoder passwordEncoder,
                     JwtUtil jwtUtil) {
    this.userRepository = userRepository;
    this.roleRepository = roleRepository;
    this.passwordEncoder = passwordEncoder;
    this.jwtUtil = jwtUtil;
  }

  // 用户注册业务
  @Transactional
  public void register(UserRegisterDTO dto) {
    if (userRepository.findByUsername(dto.getUsername()).isPresent()) {
      throw new RuntimeException("用户名已存在");
    }
    // 创建用户
    User user = new User();
    user.setUsername(dto.getUsername());
    user.setPassword(passwordEncoder.encode(dto.getPassword()));
    user.setEnabled(true);
    // 查找角色，这里注意检查数据库中的角色名是否包含隐藏的"\n"符号，避免查询失败
    Role role = roleRepository.findByName(dto.getRole()).orElseThrow(() -> new RuntimeException("角色不存在"));
    user.setRoles(Set.of(role));
    userRepository.save(user);
  }

  // 基于用户名、密码登录，若成功返回带JWT令牌的登录响应
  public UserStatusDTO login(String username, String password) {
    return userRepository.findByUsername(username)
        .filter(u -> passwordEncoder.matches(password, u.getPassword()) && u.isEnabled())
        .map(u -> {
          return new UserStatusDTO(jwtUtil.generateToken(u.getUsername()),
                                    u.getUsername(),
                                    u.roleNames());
        })
        .orElseThrow(() -> new RuntimeException("用户名或密码错误"));
  }

  // 列出所有用户
  public List<UserDTO> listAllUsers() {
    List<User> users = userRepository.findAll();
    return null;
//    return users.stream()
//        .map(user -> new UserDTO(user.getId(), user.getUsername()))
//        .toList();
  }

  public PageResult<UserDTO> getUsers(int page, int pageSize, String username) {
    Pageable pageable = PageRequest.of(page - 1, pageSize, Sort.by("id").descending());

    // 构建动态查询条件
    Specification<User> spec = (root, query, cb) -> {
      List<Predicate> predicates = new ArrayList<>();
      if (username != null && !username.isEmpty()) {
        predicates.add(cb.like(root.get("username"), "%" + username + "%"));
      }
      return cb.and(predicates.toArray(new Predicate[0]));
    };

    Page<User> userPage = userRepository.findAll(spec, pageable);

    // DTO 映射（可用 MapStruct 替代）
    List<UserDTO> dtos = userPage.getContent().stream()
        .map(this::toDto)
        .collect(Collectors.toList());

    return new PageResult<>(userPage.getTotalElements(), dtos, page, pageSize);
  }

  private UserDTO toDto(User user) {
    UserDTO dto = new UserDTO();
    dto.setId(user.getId());
    dto.setUsername(user.getUsername());
    dto.setEmail(user.getEmail());
    dto.setEnabled(user.isEnabled());
    dto.setRealName(user.getRealName());
    return dto;
  }



  // 根据名字查找用户
  public Optional<User> findByUsername(String username) {
    return userRepository.findByUsername(username);
  }
  // 更新用户
  public void updateUser(User user) {
    userRepository.save(user);
  }

  // 更改密码
  public void changePassword(String username, String oldPassword, String newPassword){
    userRepository.findByUsername(username)
        .filter(u -> passwordEncoder.matches(oldPassword, u.getPassword()))
        .ifPresent(user -> {
          user.setPassword(passwordEncoder.encode(newPassword));
          userRepository.save(user);
        });
  }

  // 用户去激活
  public void deactivateUser(String username){
    userRepository.findByUsername(username)
        .ifPresent(user -> {
          user.setEnabled(false);
          userRepository.save(user);
        });
  }

}
